/************************************************************
 * Project Name         [Thinking_In_Java]
 * File Name            [ScreenCaptureTool.java]
 * Creation Date        [12-Jul-2014]
 * 
 * Copyright© ge.y.yang@gmail.com All Rights Reserved
 * 
 * Work hard, play harder, think big and keep fit
 ************************************************************/
package pkg_02_gui.screen_capture.ui;

import java.awt.AWTException;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.HeadlessException;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.JWindow;
import javax.swing.filechooser.FileNameExtensionFilter;

/**
 * 截屏工具
 * 
 * @author 不落的太阳(Sean Yang)
 * @version 1.0
 * @since JDK 6
 * 
 */
public class ScreenCaptureTool extends JWindow {

	private static final long serialVersionUID = -1595343567972080052L;

	/** 鼠标指针被按下时的水平位置 */
	private int mouseX = -1;
	/** 鼠标指针被按下时的垂直位置 */
	private int mouseY = -1;
	/** 鼠标指针现在的位置 */
	private int mouseXNow = -1;
	/** 鼠标指针现在的位置 */
	private int mouseYNow = -1;
	/** 正方形方块的宽度 建议为偶数 */
	private final int rectWidth = 6;

	/** 是否已经按下了鼠标, 开始截图 */
	private boolean isPressedMouse = false;

	/** 常用工具类对象 */
	private Toolkit toolkit = null;

	/** 机器人类对象 */
	private Robot robot = null;

	/** 保存分辨率大小的当前屏幕显示的图像 */
	private BufferedImage image = null;

	/**
	 * 截图缺省构造函数.
	 */
	public ScreenCaptureTool() {
		toolkit = Toolkit.getDefaultToolkit();
		try {
			robot = new Robot();
			image = robot.createScreenCapture(new Rectangle(0, 0, toolkit
					.getScreenSize().width, toolkit.getScreenSize().height));
			// 构建截屏时的鼠标
			BufferedImage cursor = ImageIO.read(ScreenCaptureTool.class
					.getResource("cursor.gif"));
			setCursor(toolkit.createCustomCursor(cursor, new Point(), "gif"));
		} catch (AWTException e) {
			System.out.println("错误" + e.getMessage());
		} catch (HeadlessException e) {
			System.out.println("错误" + e.getMessage());
		} catch (IndexOutOfBoundsException e) {
			System.out.println("错误" + e.getMessage());
		} catch (IOException e) {
			e.printStackTrace();
		}
		this.setSize(new Double(toolkit.getScreenSize().getWidth()).intValue(),
				new Double(toolkit.getScreenSize().getHeight()).intValue());

		MouseEventImpl listener = new MouseEventImpl();
		addMouseListener(listener);
		addMouseMotionListener(listener);
		addKeyListener(new KeyEventImpl());

		GraphicsEnvironment environment = GraphicsEnvironment
				.getLocalGraphicsEnvironment();// 通过this对象取得GraphicsDevice
		GraphicsDevice device = environment.getDefaultScreenDevice();
		if (device.isFullScreenSupported())
			device.setFullScreenWindow(this);
		else
			JOptionPane.showMessageDialog(null, "抱歉, 您的设备不支持全屏");
		setVisible(true);
	}

	/**
	 * 绘制函数
	 */
	@Override
	public void paint(Graphics g) {
		Color c = g.getColor();
		g.drawImage(image, 0, 0, toolkit.getScreenSize().width,
				toolkit.getScreenSize().height, this);
		if (isPressedMouse) {
			// 填充矩形
			g.setColor(new Color(10, 100, 130, 10));
			g.fillRect(mouseX > mouseXNow ? mouseXNow : mouseX,
					mouseY > mouseYNow ? mouseYNow : mouseY,
					Math.abs(mouseXNow - mouseX), Math.abs(mouseYNow - mouseY));
			// 绘制矩形
			g.setColor(new Color(10, 100, 130));
			g.drawRect(mouseX > mouseXNow ? mouseXNow : mouseX,
					mouseY > mouseYNow ? mouseYNow : mouseY,
					Math.abs(mouseXNow - mouseX), Math.abs(mouseYNow - mouseY));
			// 绘制矩形边框各个脚上的小矩形
			int width = (mouseXNow - mouseX) / 2;
			int height = (mouseYNow - mouseY) / 2;
			for (int i = 0; i < 3; i++)
				for (int j = 0; j < 3; j++)
					if (i != 1 || j != 1)
						g.fillRect(mouseX + i * width - rectWidth / 2, mouseY
								+ j * height - rectWidth / 2, rectWidth,
								rectWidth);
			// 绘制大小提示
			String sizeTip = Math.abs(mouseX - mouseXNow) + "x"
					+ Math.abs(mouseY - mouseYNow);
			g.setColor(Color.BLACK);
			g.fillRect((mouseX > mouseXNow ? mouseXNow : mouseX),
					(mouseY > mouseYNow ? mouseYNow : mouseY) - 20,
					sizeTip.length() * 7, 18);
			g.setColor(Color.WHITE);
			g.drawString(sizeTip, (mouseX > mouseXNow ? mouseXNow : mouseX),
					(mouseY > mouseYNow ? mouseYNow : mouseY) - 7);
		}
		g.setColor(c);
	}

	/**
	 * 内部类: 继承适配器类, 实现鼠标事件
	 */
	private class MouseEventImpl extends MouseAdapter {
		/**
		 * 鼠标移动后坐标的变化.
		 */
		@Override
		public void mouseDragged(MouseEvent e) {
			// super.mouseDragged(e);
			mouseXNow = e.getXOnScreen();
			mouseYNow = e.getYOnScreen();
			repaint();
		}

		/**
		 * 鼠标点击后开始移动截图.
		 */
		@Override
		public void mousePressed(MouseEvent e) {
			super.mousePressed(e);
			mouseX = e.getXOnScreen();
			mouseY = e.getYOnScreen();
			if (!isPressedMouse)
				isPressedMouse = true;
		}

		/**
		 * 截图完成后, 保存图像.
		 */
		@Override
		public void mouseReleased(MouseEvent e) {
			super.mouseReleased(e);
			if (mouseX >= 0 && mouseXNow >= 0 && mouseY >= 0 && mouseYNow >= 0) {
				BufferedImage subImage = image.getSubimage(
						mouseX > mouseXNow ? mouseXNow : mouseX,
						mouseY > mouseYNow ? mouseYNow : mouseY,
						Math.abs(mouseXNow - mouseX),
						Math.abs(mouseYNow - mouseY));
				JFileChooser chooser = new JFileChooser();
				chooser.setCurrentDirectory(new File("."));
				chooser.setAcceptAllFileFilterUsed(false);
				chooser.setFileFilter(new FileNameExtensionFilter(
						"GIF文件 (*.gif)", ".gif"));
				chooser.setFileFilter(new FileNameExtensionFilter(
						"JPEG文件 (*.jpg;*.jpeg)", ".jpg", ".jpeg"));
				chooser.setFileFilter(new FileNameExtensionFilter(
						"BMP文件 (*.bmp)", ".bmp"));
				int op = chooser.showSaveDialog(null);
				if (op == JFileChooser.APPROVE_OPTION) {

					File file = chooser.getSelectedFile();
					String[] exname = ((FileNameExtensionFilter) chooser
							.getFileFilter()).getExtensions();
					try {
						ImageIO.write(subImage, "gif",
								new File(file.getAbsoluteFile() + exname[0]));
					} catch (IOException e1) {
						JOptionPane.showMessageDialog(null,
								"保存图片时发生错误:" + e1.getMessage());
					}
				}
				System.exit(0);
			}
		}

	}

	private class KeyEventImpl extends KeyAdapter {
		@Override
		public void keyTyped(KeyEvent e) {
			// super.keyPressed(e);
			System.out.println(e.getKeyChar());
			if (e.getKeyChar() == KeyEvent.VK_Z)
				System.exit(0);
		}
	}
}
